本篇同步發文在個人Blog: 一袋.NET要扛幾樓?打造容器化的ASP.NET Core網站!系列文章 - (19) 建立購物車系統 - 2
在CartApi專案新增資料夾Infrastructure/ActionResults,並新增InternalServerErrorObjectResult類別且繼承ObjectResult,此類別是用在統一回傳Status Code 500:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace CartApi.Infrastructure.ActionResults
{
public class InternalServerErrorObjectResult : ObjectResult
{
public InternalServerErrorObjectResult(object error) : base(error)
{
StatusCode = StatusCodes.Status500InternalServerError;
}
}
}
在CartApi專案新增資料夾Infrastructure/Exceptions,並新增CartDomainException類別且繼承Exception,當一些購物車服務有出問題,可以拋此異常:
using System;
namespace CartApi.Infrastructure.Exceptions
{
public class CartDomainException : Exception
{
public CartDomainException()
{
}
public CartDomainException(string message) : base(message)
{
}
public CartDomainException(string message, Exception innerException) : base(message, innerException)
{
}
}
}
在CartApi專案新增資料夾Infrastructure/Filters,並新增HttpGlobalExceptionFilter類別且實作IExceptionFilter,當Controller內部有功能異常時,依此Filter客製化要回傳的HTTP內容:
using CartApi.Infrastructure.ActionResults;
using CartApi.Infrastructure.Exceptions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Net;
namespace CartApi.Infrastructure.Filters
{
public class HttpGlobalExceptionFilter : IExceptionFilter
{
private readonly IWebHostEnvironment env;
private readonly ILogger<HttpGlobalExceptionFilter> logger;
public HttpGlobalExceptionFilter(IWebHostEnvironment env, ILogger<HttpGlobalExceptionFilter> logger)
{
this.env = env;
this.logger = logger;
}
public void OnException(ExceptionContext context)
{
logger.LogError(new EventId(context.Exception.HResult),
context.Exception,
context.Exception.Message);
if(context.Exception.GetType() == typeof(CartDomainException))
{
var json = new JsonErrorResponse
{
Messages = new[] { context.Exception.Message }
};
context.Result = new BadRequestObjectResult(json);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
}
else
{
var json = new JsonErrorResponse
{
Messages = new[] { "An error occured. Try it again" }
};
if (env.IsDevelopment())
{
json.DeveloperMessage = context.Exception;
}
context.Result = new InternalServerErrorObjectResult(json);
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
}
context.ExceptionHandled = true;
}
private class JsonErrorResponse
{
public string[] Messages { get; set; }
public object DeveloperMessage { get; set; }
}
}
}
在appSettings.json,新增Redis的連線資訊,由於本機有安裝過的Redis,於是配置它為6377 port,對應到Docker的配置仍是預設的6379 port:
在CartApi根目錄新增CartSettings.cs類別,只有一個ConnectionString屬性,是用來讀設定檔:
namespace CartApi
{
public class CartSettings
{
public string ConnectionString { get; set; }
}
}
-----------------------------------------------------
之後再來寫Controller和註冊Startup的方法